﻿using Candy.Infrastructure;
using Candy.Model;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.ObjectModel;
using System.Linq;

namespace Candy.ViewModel
{
    public class PhylogeniesViewModel : CandyViewModelBase
    {

        private bool _isBusy;
        public bool IsBusy
        {
            get
            {
                return _isBusy;
            }
            set
            {
                _isBusy = value;
                if (_isBusy == true)
                    base.ReportProgress();
                else
                    base.FinishProgress();
            }
        }

        private FamilyEditViewModel _selectedFamily;
        public FamilyEditViewModel SelectedFamily
        {
            get
            {
                return _selectedFamily;
            }
            set
            {
                if (_selectedFamily != value)
                {
                    
                    //if (_selectedFamily != null)
                    //    _selectedFamily.Entity.Phylogenies.EntityAdded -= Phylogenies_EntityAdded;
                    _selectedFamily = value;

                    RaisePropertyChanged("SelectedFamily");
                    Load.Execute(null);
                   // _selectedFamily.Entity.Phylogenies.EntityAdded += Phylogenies_EntityAdded;
                }
            }
        }

       

        private ObservableCollection<PhylogenyEditViewModel> _phylogenies;
        public ObservableCollection<PhylogenyEditViewModel> Phylogenies
        {
            get
            {
                return _phylogenies;
            }
            set
            {
                _phylogenies = value;
                RaisePropertyChanged("Phylogenies");
            }
        }

        private PhylogenyEditViewModel _selectedPhylogeny;
        public PhylogenyEditViewModel SelectedPhylogeny
        {
            get
            {
                return _selectedPhylogeny;
            }
            set
            {
                _selectedPhylogeny = value;
                RaisePropertyChanged("SelectedPhylogeny");
            }
        }



        IDataService _dataService;
        INavigationService _navigationService;
        public PhylogeniesViewModel(IDataService dataService, INavigationService navigationService)
        {
            _dataService = dataService;
            _navigationService = navigationService;

            if (IsInDesignMode)
            {
                try
                {
                    try
                    {
                        SelectedFamily = new FamilyEditViewModel(_dataService, _navigationService, new System.ServiceModel.DomainServices.Client.EntitySet<Web.Data.FamilyDto>(), new Web.Data.FamilyDto
                            {
                                Name = "Bla"
                            });

                        _load.Execute(null);
                    }
                    catch (Exception ex)
                    {
                        System.Windows.MessageBox.Show(ex.Message);
                    }
                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show(ex.StackTrace);
                }
            }

            MessengerInstance.Register<NotificationMessage<FamilyEditViewModel>>(this, msg =>
            {
                if (msg.Notification == ViewModelMessageTypes.SelectFamily)
                    SelectedFamily = msg.Content;
            });

            Phylogenies = new ObservableCollection<PhylogenyEditViewModel>();
            _dataService.Phylogenies.EntityAdded +=Phylogenies_EntityAdded;
        }


        void Phylogenies_EntityAdded(object sender, System.ServiceModel.DomainServices.Client.EntityCollectionChangedEventArgs<Web.Data.PhylogenyDto> e)
        {
            PhylogenyEditViewModel vm = new PhylogenyEditViewModel(_dataService, _navigationService, e.Entity);
            Phylogenies.Add(vm);
            SelectedPhylogeny = vm;
        }

        private RelayCommand _load;
        public RelayCommand Load
        {
            get
            {
                return _load ?? (_load = new RelayCommand(ExecLoad, CanLoad));
            }
        }

        /// <summary>
        /// Checks whether the Load command is executable
        /// </summary>
        private bool CanLoad()
        {
            return true;
        }

        /// <summary>
        /// Executes the Load command 
        /// </summary>
        private void ExecLoad()
        {
            if (this.SelectedFamily != null)
            {
                _dataService.Phylogenies.EntityAdded -= Phylogenies_EntityAdded;
                IsBusy = true;
                _dataService.LoadPhylogeniesAsync(SelectedFamily.Entity.Id, op =>
                    {
                      
                        IsBusy = false;
                        if (op.HasError)
                        {
                            base.HandleDomainError(op, "Loading Phylogenies failed.");
                        }
                        else
                        {
                          
                            Phylogenies = new ObservableCollection<PhylogenyEditViewModel>(op.Entities.Select(x => new PhylogenyEditViewModel(_dataService, _navigationService, x)));
                            SelectedPhylogeny = Phylogenies.FirstOrDefault();

                            _dataService.Phylogenies.EntityAdded += Phylogenies_EntityAdded;
                        }
                    });
            }
            else
            {

            }
        }


        private RelayCommand _createPhylogeny;
        public RelayCommand CreatePhylogeny
        {
            get
            {
                return _createPhylogeny ?? (_createPhylogeny = new RelayCommand(ExecCreatePhylogeny, CanCreatePhylogeny));
            }
        }

        /// <summary>
        /// Checks whether the CreatePhylogeny command is executable
        /// </summary>
        private bool CanCreatePhylogeny()
        {
            return true;
        }

        /// <summary>
        /// Executes the CreatePhylogeny command 
        /// </summary>
        private void ExecCreatePhylogeny()
        {
            var vm = new PhylogenyEditViewModel(_dataService, _navigationService, new Web.Data.PhylogenyDto() { FamilyId = SelectedFamily.Entity.Id, ProjectId = _dataService.LoadedProject.Id });
            vm.Edit.Execute(null);
            _navigationService.ShowPhylogenyEditor(vm);
        }




        private RelayCommand<PhylogenyEditViewModel> _deletePhylogeny;
        public RelayCommand<PhylogenyEditViewModel> DeletePhylogeny
        {
            get
            {
                return _deletePhylogeny ?? (_deletePhylogeny = new RelayCommand<PhylogenyEditViewModel>(ExecDeletePhylogeny, CanDeletePhylogeny));
            }
        }

        /// <summary>
        /// Checks whether the DeletePhylogeny command is executable
        /// </summary>
        private bool CanDeletePhylogeny(PhylogenyEditViewModel val)
        {
            return val != null;
        }

        /// <summary>
        /// Executes the DeletePhylogeny command 
        /// </summary>
        private void ExecDeletePhylogeny(PhylogenyEditViewModel val)
        {
            var fam = _dataService.Families.SingleOrDefault(x => x.Id == val.Entity.FamilyId);

            if (fam != null)
            {
                IsBusy = true;
                fam.Phylogenies.Remove(val.Entity);
                _dataService.Phylogenies.Remove(val.Entity);
                _dataService.SubmitAsync(op =>
                    {
                        IsBusy = false;
                        if (op.HasError)
                        {
                            base.HandleDomainError(op, "Deleting phylogenie failed.");
                        }
                        else
                        {
                            Phylogenies.Remove(val);
                            SelectedPhylogeny = Phylogenies.FirstOrDefault();
                        }
                    });
            }
        }



        private RelayCommand<PhylogenyEditViewModel> _editPhylogeny;
        public RelayCommand<PhylogenyEditViewModel> EditPhylogeny
        {
            get
            {
                return _editPhylogeny ?? (_editPhylogeny = new RelayCommand<PhylogenyEditViewModel>(ExecEditPhylogeny, CanEditPhylogeny));
            }
        }

        /// <summary>
        /// Checks whether the EditPhylogeny command is executable
        /// </summary>
        private bool CanEditPhylogeny(PhylogenyEditViewModel val)
        {
            return val != null;
        }

        /// <summary>
        /// Executes the EditPhylogeny command 
        /// </summary>
        private void ExecEditPhylogeny(PhylogenyEditViewModel val)
        {
            val.Edit.Execute(null);
            _navigationService.ShowPhylogenyEditor(val);
        }



    }
}
